########################################################################
#  Searx-Qt - Lightweight desktop application for Searx.
#  Copyright (C) 2020-2022  CYBERDEViL
#
#  This file is part of Searx-Qt.
#
#  Searx-Qt is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  Searx-Qt is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
########################################################################

class EnginesModel:
    def __init__(self, handler=None):
        self._handler = handler
        self._data = {}
        if handler:
            self._data = handler.engines

    @property
    def handler(self): return self._handler

    def __contains__(self, name):
        return bool(name in self._data)

    def __getitem__(self, engineName):
        return Engine(engineName, self._data[engineName])

    def __str__(self): return str([engineName for engineName in self.keys()])

    def __repr__(self): return str(self)

    def __len__(self): return len(self._data)

    def data(self): return self._data

    def items(self):
        return [
            (name, Engine(name, data))
            for name, data in self._data.items()
        ]

    def keys(self): return self._data.keys()

    def values(self):
        return [
            Engine(name, data)
            for name, data in self._data.items()
        ]

    def categories(self):
        """ Returns a list with all categories, collected from instances.
        """
        categories = []
        for engine in self.values():
            for cat in engine.categories:
                if cat not in categories:
                    categories.append(cat)
        return categories

    def getByCategory(self, category):
        """ Returns a list with Engine's that are part of the given
        category.

        @param category: category name
        @type category: str

        @rtype: list
        """
        result = []
        for engine in self.values():
            if category in engine.categories:
                result.append(engine)

        return result


class Stats2Engines(EnginesModel):
    def __init__(self, handler):
        """
        @param handler: Object that holds the instances.json data.
        @type handler: core.instances.Stats2
        """
        EnginesModel.__init__(self, handler)


class Engine:
    def __init__(self, engineName, engineData):
        self._data = engineData
        self._name = engineName

    @property
    def data(self):
        return self._data

    @property
    def name(self):
        """
        @return: returns the name of this engine
        @rtype: str
        """
        return self._name

    @property
    def categories(self):
        """
        @return: list with search categories
        @rtype: list
        """
        return self._data.get('categories', [])

    @property
    def languageSupport(self):
        """
        @return: If this engine has language support
        @rtype: bool
        """
        return self._data.get('language_support', False)

    @property
    def paging(self):
        """
        @return: If this engine has paging support
        @rtype: bool
        """
        return self._data.get('paging', False)

    @property
    def safesearch(self):
        """
        @return: If this engine has safe-search support
        @rtype: bool
        """
        return self._data.get('safesearch', False)

    @property
    def shortcut(self):
        """
        @return: Shortcut name for this engine
        @rtype: str
        """
        return self._data.get('shortcut', "")

    @property
    def timeRangeSupport(self):
        """
        @return: If this engine has time-range support
        @rtype: bool
        """
        return self._data.get('time_range_support', False)
